package cn.qayy.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import cn.qayy.constants.Constant;
import cn.qayy.dao.BidMapper;
import cn.qayy.dao.PolicyMapper;
import cn.qayy.dto.BasisDTO;
import cn.qayy.dto.BidDTO;
import cn.qayy.po.Basis;
import cn.qayy.po.Bid;
import cn.qayy.po.Policy;
import cn.qayy.service.IBidService;
import cn.qayy.service.IPolicyService;
import cn.qayy.service.Uploadable;
import cn.qayy.utils.DownLoadUtil;
import cn.qayy.utils.ServletContextUtils;
import cn.qayy.utils.StringUtil;

/***
 * @author wy
 *
 */
@Service("bidServiceImpl")
@SuppressWarnings("all")
public class BidImpl implements IBidService {
	private Logger logger = LoggerFactory.getLogger(BidImpl.class);

	@Resource
	public BidMapper bidMapper;
	
	@Resource(name = "policyServiceImpl")
	private IPolicyService policyService = null;

	@Override
	public PageInfo<Map<String, Object>> selectBidBy(Map<String, Object> params) throws Exception{
		if (params != null && params.size() > 0) {
			DownLoadUtil.set("BidDTO",params);
			if (params.containsKey("pageNumber") && params.containsKey("pageSize")) {
				Integer pageNum = Integer.parseInt(params.get("pageNumber") == null ? "1" : params.get("pageNumber").toString());
				Integer pageSize = Integer.parseInt(params.get("pageSize") == null ? "12" : params.get("pageSize").toString());
				PageHelper.startPage(pageNum, pageSize);
			}
			List<Map<String, Object>> list = bidMapper.selectBidBy(params);
			PageInfo<Map<String, Object>> pageInfo = new PageInfo<Map<String, Object>>(list);
			return pageInfo;
		}
		return null;
	}

	@Override
	public List<BidDTO> selectBidForDown(@RequestParam Map<String, Object> params) throws Exception {
		List<BidDTO> list = bidMapper.selectBidForDown(params);
		return list;
	}

	@Override
	public Bid selectBidByID(@RequestParam Integer bidId) throws Exception {
		return bidMapper.selectByPrimaryKey(bidId);
	}

	@Override
	public List<? extends String> selectPzKeys() throws Exception {
		return bidMapper.selectPzKeys();
	}
	/**
	 * 标测库、中标库 和协议是一体的，匹配更新时协议时间取值范围：开始时间<=x<=结束时间。
	 * 
	 * 中标库同步更新协议，注意：如果有特殊中标时，最后还必须更新下特殊中标库，优先级：
	 * 1、入货乙方不同，中标价不同
	 * 2、地市不同，中标价不同。
	 * 
	 * 更新的顺序：先处理优先级低的，处理地市，在处理入货乙方。
	 * @param list
	 * @throws Exception
	 */
	private void updatePolicyByBid(List list) throws Exception {
		for (Object obj : list) {
			Bid p = (Bid)obj;
			Map<String,Object> params = new HashMap<String,Object>();
			Set<String> provinces = new HashSet<String>();
			Set<String> citys = new HashSet<String>();
			Set<String> products = new HashSet<String>();
			Set<String> packs = new HashSet<String>();
			Set<String> cnames = new HashSet<String>();
			Set<String> status = new HashSet<String>();
			status.add("4");
			status.add("5");
			status.add("6");
			//只更新4状态5状态6状态的协议
			params.put("status", status);
			//省份
			if(StringUtil.isNotBlank(p.getProvince())) {
				provinces.add(p.getProvince());
				params.put("provinces", provinces);
			}
			//地市
			if(StringUtil.isNotBlank(p.getCity())) {
				citys.add(p.getCity());
				params.put("citys", citys);
			}
			//品种
			if(StringUtil.isNotBlank(p.getProduct())) {
				products.add(p.getProduct());
				params.put("products", products);
			}
			//包装
			if(StringUtil.isNotBlank(p.getPack())) {
				packs.add(p.getPack());
				params.put("packs", packs);
			}
			//入货乙方
			if(StringUtil.isNotBlank(p.getTerminal())) {
				cnames.add(p.getTerminal());
				params.put("cnames",cnames);
			}
			if(StringUtil.isNotBlank(p.getStime())) {
				params.put("stime", p.getStime());//开始时间
			}
			if(StringUtil.isNotBlank(p.getEtime())) {
				params.put("etime", p.getEtime());//结束时间
			}
			//根据中标库参数获取协议
			List<Policy> selectPolicys = policyService.selectPolicys(params);
			//若获取到了则匹配
			if(selectPolicys != null && !selectPolicys.isEmpty()) {
				for(Policy po:selectPolicys) {
					po.setZhongbiaojia(p.getZbj());
				}
				//同步更新协议
				policyService.updateByList(selectPolicys);
				//协议更新后，同步更新流向
				policyService.updatePlansByPolicys(selectPolicys);
			} 
		}
	}
	@Override
	public int updateByList(List list) throws Exception{
		updatePolicyByBid(list);
		return bidMapper.updateByList(list);
	}

	@Override
	public int deleteByList(List list) throws Exception{
		return bidMapper.deleteByList(list);
	}

	@Override
	public int insert(Object bean) throws Exception{
		return bidMapper.insert(bean);
	}

	@Override
	public int update(Object bean) throws Exception{
		return bidMapper.updateByPrimaryKey(bean);
	}

	@Override
	public int delete(Object bean) throws Exception{
		return bidMapper.delete(bean);
	}

	@Override
	public int insertByList(List list) throws Exception{
		updatePolicyByBid(list);
		return bidMapper.insertByList(list);
	}

	@Override
	public Bid getBid(Map<String,Object> params) throws Exception{
		return bidMapper.getBid(params);
	}

	@Override
	public List<Bid> selectByMap(Map<String, Object> params) {
		return bidMapper.selectByMap(params);
	}

	@Override
	public List<Integer> selectIdsByMap(Map<String, Object> params) {
		return bidMapper.selectIdsByMap(params);
	}

	@Override
	public void persistence(Map<String, List<Uploadable>> map, HttpServletRequest request, Object object)
			throws Exception {
		List<Uploadable> listE = map.get("E");
		List<Bid> plist = new ArrayList<Bid>();
		if (listE != null && !listE.isEmpty()) {
			List<Bid> db_list = new ArrayList<Bid>(listE.size()+1);
			List<String> ids = new ArrayList<String>(listE.size()+1);
			for (Uploadable u : listE) {
				BidDTO dto = (BidDTO)u;
				ids.add(dto.getId());
			}
			db_list = bidMapper.selectByIds(ids);
			//校验Excel上传的id是否正确
			if(ids.size() != db_list.size()) {
				throw new Exception(Constant.FAIL_MSG_ID);
			}
			
			// 待更新的实体list
			List<Bid> list = new ArrayList<Bid>(listE.size() + 1);
			for (Uploadable u : listE) {
				BidDTO dto = (BidDTO) u;
				for(Bid b:db_list) {
					if(b.getId().toString().equals(dto.getId())) {
						plist.add(b);
						b.setByDTO(dto);
						list.add(b);
						continue;
					}
				}
			}
			if(!list.isEmpty()) {
				removeToContext(plist);
				try {
					bidMapper.updateByList(list);
				} catch (Exception e) {
					addToContext(plist);
					throw e;
				}
				//更新中标库后，同步更新协议
				updatePolicyByBid(list);
				//添加缓存
				addToContext(list);
			}
		}
		List<Uploadable> listN = map.get("N");
		if (listN != null && !listN.isEmpty()) {
			// 待新增的实体list
			List<Bid> list = new ArrayList<Bid>(listN.size() + 1);
			for (Uploadable u : listN) {
				BidDTO dto = (BidDTO) u;
				// 封装数据
				Bid bid = new Bid();
				bid.setByDTO(dto);
				list.add(bid);
			}
			if(!list.isEmpty()) {
				bidMapper.insertByList(list);
				//更新中标库后，同步更新协议
				updatePolicyByBid(list);
				//添加缓存
				addToContext(list);
			}
		}
	}
	/***
	 * 持久化中标库后，更新context缓存
	 * 
	 * @param list
	 */
	private void addToContext(List<Bid> list) {
		/***
		 * 获取项目上下文的共享数据
		 */
		ServletContext servletContext = ServletContextUtils.getServletContext();
		// 中标库keys
		Set<String> pzKeys = (Set<String>) servletContext.getAttribute("pzKeys");
		for (Bid b : list) {
			pzKeys.add(StringUtil.concat(b.getProvince(), b.getCity(), b.getTerminal(), b.getProduct(), b.getPack(),
					b.getStime(), b.getEtime(), b.getId() + ""));
		}
	}
	/***
	 * 持久化中标库后，更新context缓存
	 * 
	 * @param list
	 */
	private void removeToContext(List<Bid> list) {
		/***
		 * 获取项目上下文的共享数据
		 */
		ServletContext servletContext = ServletContextUtils.getServletContext();
		// 中标库keys
		Set<String> pzKeys = (Set<String>) servletContext.getAttribute("pzKeys");
		for (Bid b : list) {
			pzKeys.remove(StringUtil.concat(b.getProvince(), b.getCity(), b.getTerminal(), b.getProduct(), b.getPack(),
					b.getStime(), b.getEtime(), b.getId() + ""));
		}
	}
}
